package com.copy.parse;

import com.copy.mark.Clone;
import com.copy.mark.EasyCopy;
import com.copy.mark.ParamMaps;
import com.copy.pojo.BeanMetaData;
import com.copy.pojo.BeanMethod;
import com.copy.scan.ScanBasePackageStrategy;
import com.copy.scan.spring.ScanBasePackageBySpringHandler;

import java.lang.reflect.Method;

/**
 * author: liziyun
 * date: 2019-9-30
 * email: root@ofo.email
 * describe: 注解解析器
 *      解析方法上的注解信息,@ParamMaps注解 和 @ParamMap注解
 *      设计模式: 模板方法模式
 */
public abstract class ParseAnnotationMetaDataStrategyHandler extends ScanBasePackageBySpringHandler implements ParseAnnotationMetaDataStrategy {
    public ParseAnnotationMetaDataStrategyHandler(ScanBasePackageStrategy scanBasePackageStrategy) {
        super(scanBasePackageStrategy);
    }

    public BeanMetaData getBeanDefinition(Class cls){

        BeanMetaData definition=null;
        if (cls.isAnnotationPresent(EasyCopy.class)){
            definition = new BeanMetaData(cls.getSimpleName(),cls);
            //提取映射关系
            Method[] methods = cls.getDeclaredMethods();
            for (Method method : methods) {
                method.setAccessible(true);
                //方法Pojo
                BeanMethod beanMethod =new BeanMethod(method);
                //注解对应关系解析
                ParamMaps paramMapsAnnotation = method.getDeclaredAnnotation(ParamMaps.class);
                if (paramMapsAnnotation!=null){
                    beanMethod.setOpenParam(true);
                    if (paramMapsAnnotation.eagerInstance()){
                        beanMethod.setEagerInstance(true);
                    }
                }else{//方法名自动匹配:ageByAgeAndHeightByHeight
                    beanMethod.setOpenParam(false);
                    //两个实例化对象，相互拷贝
                    if (method.getParameterTypes().length==2){
                        System.out.println(beanMethod.getMethod().getName()+":"+method.getParameterTypes().length);
                        beanMethod.setEagerInstance(true);//已经提前实例化
                    }
                }
                //是否@Clone
                if (method.getDeclaredAnnotation(Clone.class)!=null){
                    beanMethod.setClone(true);
                }
                //组装到BeanMetaData
                 definition.addBeanMethods(method,beanMethod);
            }
        }
        return definition;
    }


}
